<?php

namespace App\Services;

use App\Models\MoneyDeposit;
use App\Models\MoneyLog;
use App\Models\MoneyPartner;
use App\Models\MoneyWithdraw;
use App\Models\UserBank;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use App\Models\Money;
use App\Models\User;
use App\Models\UserLevel;
use App\Models\HallPartnerConfig;
use common\utils\SysCode;

class MoneyService
{
    /**
     * 获取用户总余额(主钱包+子钱包)
     * @param int $user_id 用户ID
     * @param string $password 取现密码
     * @return bool
     */
    public static function getTotalMoney($id)
    {
        $money = Money::select('balance')->where('user_id', $id);
        $money_child = MoneyPartner::select(DB::raw('sum(balance) as balance'))->where('user_id', $id);
        $re = $money->unionAll($money_child)->get()->toArray();
        return array_sum(array_column($re, 'balance'));
    }

    /**
     * 校验取现密码
     * @param int $user_id 用户ID
     * @param string $password 取现密码
     * @return bool
     */
    public static function validPassword($user_id, $password)
    {
        $m = Money::where(['user_id' => $user_id])->select(['salt', 'password'])->first();
        if (!$m) {
            return error_exit(SysCode::USER_NOT_FOUND);
        }
        return password_encrypt($password, $m->salt) == $m->password;
    }

    /**
     * 获取主钱包
     * @param int $user_id 用户ID
     * @return Illuminate\Database\Eloquent\Model|null
     */
    public static function getWallet($user_id)
    {
        return Money::select(['balance', 'freeze_withdraw', 'status'])->where(['user_id' => $user_id])->first();
    }

    /**
     * 获取子钱包
     * @param int $user_id 用户ID
     * @param int $partner_id 子钱包ID
     * @return Illuminate\Database\Eloquent\Model|null
     */
    public static function getWalletPartner($user_id, $partner_id)
    {
        return HallPartnerConfig::leftJoin('money_partner as mp', function ($query) use ($user_id) {
            $query->on('hall_partner_config.partner_id', '=', 'mp.partner_id')
                ->where('mp.user_id', $user_id);
        })
            ->select([
                DB::raw('CONCAT(hall_partner_config.partner_name, "子钱包") as name'),
                DB::raw('IFNULL(`mp`.`balance`, 0) as balance'),
            ])
            ->where(['hall_partner_config.partner_id' => $partner_id])
            ->first();;
    }

    /**
     * 获取子钱包列表
     * @return array|null
     */
    public static function getPartnerList()
    {
        return HallPartnerConfig::select(['partner_id', DB::raw('CONCAT(`partner_name`, "子钱包") as name')])->where(['status' => 1])->orderBy('sort')->get();
    }

    /**
     * 生成提款订单
     * @param $user array 用户信息
     * @param $withdraw_money int 提款金额
     * @param $withdraw_card int 提款银行卡id
     */
    public static function addWithdrawOrder($user, $withdraw_money, $withdraw_card, $fee, $ip, $remark = "")
    {
        //判断主钱包
        $wallet = Money::where(['user_id' => $user['id']])->first();
        $primaryBalance = $wallet['balance'];
        if ($withdraw_money > $primaryBalance) {
            error_exit(SysCode::BANK_WITHDRAW_MONEY_ERROR, ['withdraw_money' => amount_format($withdraw_money), 'balance' => amount_format($primaryBalance)]);
        }
        //查询用户的余额
        $bank = UserBank::where(['user_id' => $user['id'], 'bank_id' => $withdraw_card])->first();
        if (empty($bank)) {
            error_exit(SysCode::BANK_WITHDRAW_BANK_NOT_EXIST);
        }

        $check_id_first_withdraw = MoneyWithdraw::where(['user_id' => $user['id'], 'status' => 2])->orderBy('id', 'desc')->first();
        $first = 0;
        if (empty($check_id_first_withdraw)) {
            $first = 1;
        }
        $previous_time = empty($check_id_first_withdraw) ? "" : $check_id_first_withdraw['created_at']->format("Y-m-d H:i:s");

        //查询用户层级
        $levelInfo = User::where(['id' => $user['id']])->first();
        $userLevelConfig = UserLevel::where(['id' => $levelInfo['level_id']])->first();
        $tradeNo = date("YmdHis") . rand(pow(10, 3), pow(10, 4) - 1);

        //查询用户资金表
        $user_money = Money::where(['user_id' => $user['id']])->first();


        //计算投注和打码量
        $valid_bet_total = $valid_bet_require = 0;

        if (isset($fee['list']) && is_array($fee['list'])) {
            foreach ($fee['list'] as $k => $v) {
                $valid_bet = $v['valid_bet'];
                $widthdraw_bet = isset($v['withdraw_bet_principal']) ? (int)$v['withdraw_bet_principal'] : 0;
                $withdraw_bet_coupon = isset($v['withdraw_bet_coupon']) ? (int)$v['withdraw_bet_coupon'] : 0;
                $valid_bet_total += $valid_bet;
                $valid_bet_require += $withdraw_bet_coupon;
                $valid_bet_require += $widthdraw_bet;
            }
        }
        $user_bank_info = [
            'bank' => $bank['id'],
            'name' => $bank['name'],
            'card' => $bank['card'],
            'address' => $bank['address']
        ];
        $withdraw_model = [
            'user_id' => $user['id'],
            'level_id' => $userLevelConfig['id'],
            'order_number' => $tradeNo,
            'amount' => $withdraw_money,
            'coupon_amount' => $fee['coupon'],
            'coupon_amount_before' => $fee['coupon'],
            'withdraw_validbet' => $valid_bet_require,
            'validbet' => $valid_bet_total,
            'fee' => $fee['withdraw_fee'],
            'fee_before' => $fee['withdraw_fee'],
            'admin_fee' => $fee['admin_fee'],
            'admin_fee_before' => $fee['admin_fee'],
            'user_bank_id' => $withdraw_card,
            'user_bank_info' => json_encode($user_bank_info),
            'has_fee' => $fee['withdraw_fee'] > 0 ? 1 : 0,
            'created_admin_id' => 0,
            'previous_time' => $previous_time,
            'check_time' => $fee['date_from'],
            'type' => 1,
            'ip' => $ip,
            'remark' => $remark,
        ];
        $log_model = [
            'user_id' => $user['id'],
            'username' => $user['username'],
            'order_number' => $tradeNo,
            'category' => 2,
            'type' => 201,//todo 会员提款
            'amount' => $withdraw_money,
            'balance' => $user_money['balance'],
            'balance_before' => $user_money['balance'] - $withdraw_money,
        ];


        DB::beginTransaction();
        try {
            //修改钱包余额
            $userMoney = Money::where(['user_id' => $user['id']])->first();

            $freeze_money = $withdraw_money;
            $updatePartner = [
                'balance' => $userMoney['balance'] - $withdraw_money,
                'freeze_withdraw' => $freeze_money
            ];
            Money::where(['user_id' => $user['id']])->update($updatePartner);
            //生成订单
            $withdrawOrder = new MoneyWithdraw($withdraw_model);
            if (!$withdrawOrder->save()) {
                DB::rollBack();
                return error_exit(SysCode::BANK_WITHDRAW_ERROR);
            }

            //生成流水
            $withdrawMoneyLog = new MoneyLog($log_model);
            if (!$withdrawMoneyLog->save()) {
                DB::rollBack();
                return error_exit(SysCode::BANK_WITHDRAW_ERROR);
            }
            DB::commit();

        } catch (\Throwable $e) {
            DB::rollBack();
            return error_exit(SysCode::BANK_WITHDRAW_ERROR);
        }
        return SysCode::OK;
    }


    /**
     * 获取用户的存提记录
     * @param $user_id
     */
    public static function getUserMoneyList($user_id, $start_time, $end_time, $page = 1, $page_size = 15)
    {
        $where_withdraw = [
            ['user_id', '=', $user_id],
            ['status', '=', 2],
            ['created_at', '>=', $start_time],
            ['created_at', '<=', $end_time]
        ];
        $withdrawList = MoneyWithdraw::where($where_withdraw)->select(['amount', 'order_number', 'status', 'remark', 'created_at', 'type'])->get()->toArray();
        foreach ($withdrawList as $k => $v) {
            if ($v['type'] == 1) {
                $withdrawList[$k]['type_name'] = '会员提款';
            } elseif ($v['type'] == 2) {
                $withdrawList[$k]['type_name'] = '手动提款';
            } else {
                $withdrawList[$k]['type_name'] = '手动减少余额';
            }
        }
        $typeList = [
            '1' => '银行柜台',
            '2' => 'ATM现金入款',
            '3' => 'ATM自动柜员机',
            '4' => '手机转账',
            '5' => '支付宝转账',
            '6' => '财付通',
            '7' => '微信支付',
            '8' => '手动存款',
            '9' => '网银转账'
        ];
        $where_despoit = [
            ['user_id', '=', $user_id],
            ['created_at', '>=', $start_time],
            ['created_at', '<=', $end_time],
        ];
        $deppostiList = MoneyDeposit::where($where_despoit)->select(['amount', 'order_number', 'status', 'remark', 'created_at', 'offline_pay_type as type'])->whereIn('offline_pay_type', range(1, 9))->get()->toArray();

        foreach ($deppostiList as $ke => $va) {
            $type = $va['type'];
            $deppostiList[$ke]['type_name'] = isset($typeList[$type]) ? $typeList[$type] : "";
        }
        $withdrawList = array_merge($withdrawList, $deppostiList);
        array_multisort(array_column($withdrawList, 'created_at'), SORT_DESC, $withdrawList);
        return PageService::formatPageData(empty($withdrawList) ? [] : array_slice($withdrawList, ($page - 1) * $page_size, $page_size), $page, $page_size, count($withdrawList));
    }

    //回收所有钱包
    public static function recoveryWallet($user)
    {
        $user = Auth::user();
        $child_wallet = MoneyPartner::where(['user_id'=>$user['id']])->get()->toArray();
        foreach($child_wallet as $ke =>$value){
            if($value['balance'] >0){
                $checkParams = [
                    'cid'=>$value['partner_id'],
                    'type'=>2,
                    'amount'=>amount_format($value['balance'])
                ];
                FundsService::exchange($user, $checkParams);
            }
        }
        return SysCode::OK;
    }

}
